package com.oedtech.esl.controller.security;

import com.alibaba.fastjson.JSONObject;
import com.oedtech.esl.controller.BaseController;
import com.oedtech.esl.json.JsonResult;
import com.oedtech.esl.model.sys.Role;
import com.oedtech.esl.model.sys.Store;
import com.oedtech.esl.model.sys.User;
import com.oedtech.esl.repository.sys.RoleDao;
import com.oedtech.esl.repository.sys.StoreDao;
import com.oedtech.esl.repository.sys.UserDao;
import com.oedtech.esl.service.securityService.UserNomalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.security.Principal;
import java.util.*;

@RestController
@RequestMapping("/user_rest")
public class UserRestController extends BaseController{


    @Autowired
    private UserDao userDao;

    @Autowired
    private UserNomalService userNomalService;

    @Autowired
    private RoleDao roleDao;
    @Autowired
    private StoreDao storeDao;




    //保存修改
    @RequestMapping(value="/save_change",method= RequestMethod.POST)
    public JsonResult saveChange(@RequestBody User user){
        Authentication auth= SecurityContextHolder.getContext().getAuthentication();
        userNomalService.changePwd(user.getId(),user.getPassword(),auth.getName());
        return new JsonResult("success",null,"null");
    }

    /**
     * 新增或修改用户
     * @param user  用户实体类
     * @return
     */
    @PostMapping("/add_change_user")
    public JsonResult AddOrChangeUser(@RequestBody User user){

        return userNomalService.AddOrChangeUser(user);
    }

    /**
     * 修改密码
     * @param id  用户id
     * @param password  新密码
     * @param principal   获取当前登录用户
     * @return
     */
    @PostMapping("/change_password")
    public JsonResult changePwd(Long id,String password,Principal principal){

        return userNomalService.changePwd(id, password,principal.getName());
    }

    /**
     * 删除用户
     * @param jo
     * @param principal
     * @return
     */
    @PostMapping("/delete_user")
    public JsonResult deleteUser(@RequestBody JSONObject jo,Principal principal)
    {

        if(jo.get("userId")==null||jo.get("username")==null){
            logger.warn("delete user fail:userId or username is null or empty");
            return new JsonResult("error","缺少必要参数");
        }
        String username = jo.getString("username");
        Long userId = jo.getLong("userId");
        if(username.equals(principal.getName())){
            logger.warn("delete user fail:can not delete user itself");
            return new JsonResult("error","不能删除登陆账号本身");
        }

        userDao.deleteById(userId);
        return new JsonResult("success",null);
    }


    @RequestMapping("/find_roleAndStore")
    public Map<String,Object>findROleAndStore(Principal principal){
        Integer sourceFlag=userDao.findSourceFlagByUsername(principal.getName());
        List<Store> storeList;
        List<Role>roleList;
        if(sourceFlag==0){
            storeList =storeDao.findAll();
            roleList =roleDao.findAll();
        }else {
            storeList=storeDao.findAllBySourceFlag(sourceFlag);
//            roleList=roleDao.findAllNotSupper();
            roleList = new ArrayList<>();
        }

        Map<String, Object> map = new HashMap<>();
        map.put("storeList", storeList);
        map.put("roleList", roleList);
        return map;
    }

//    @PostMapping("/save_role_relate")
//    public JsonResult saveRoleRelate(@RequestParam("roleIDs")Long[]roleIDs,@RequestParam("userId")Long userId,Principal principal){
//        userNomalService.saveRoleRelate(roleIDs,userId,principal.getName());
//        return new JsonResult("success",null);
//    }
    @PostMapping("/save_role_relate")
    public JsonResult saveRoleRelate(@RequestBody JSONObject jo, Principal principal){
        if(jo.get("roleIDs")==null||jo.get("userId")==null)return new JsonResult("error","必要参数不能空");
       List<Long>roleIDs= JSONObject.parseArray(jo.getString("roleIDs"),Long.class);

        Long userId=jo.getLong("userId");
        userNomalService.saveRoleRelate(roleIDs,userId,principal.getName());
        return new JsonResult("success",null);
    }
//    @PostMapping("/save_store_relate")
//    public JsonResult saveStoreRelate(@RequestParam("storeCodes")String[]storeCodess,@RequestParam("userId")Long userId,Principal principal){
//        userNomalService.saveStoreRelate(storeCodess,userId,principal.getName());
//        return new JsonResult("success",null);
//    }
//    @PostMapping("/save_store_relate")
    public JsonResult saveStoreRelate(@RequestBody JSONObject jo,Principal principal){
        try {
            if (jo.get("storeCodes") == null || jo.get("userId") == null) return new JsonResult("error", "必要参数不能空");
            List<String> storeCodes = jo.getJSONArray("storeCodes").toJavaList(String.class);

//        =JSONObject.parseArray(jo.getString("storeCodes"),String[]);
            Long userId = jo.getLong("userId");
            userNomalService.saveStoreRelate(storeCodes, userId, principal.getName());
            return new JsonResult("success", null);
        }catch (Exception e){
            logger.error("",e);
            return new JsonResult("error", null);

        }
    }


    /**
     * 用户列表按资源获取再分页
     * @param page
     * @param size
     * @param sortStr
     * @param sortAscOrDesc
     * @param searchObj
     * @param principal
     * @return
     */
    @RequestMapping("/listByPage")
    @ResponseBody
    public Page<User> listByPage(int page, int size, String sortStr, boolean sortAscOrDesc, String searchObj, Principal principal)
    {

        Integer sourceFlag=userDao.findSourceFlagByUsername(principal.getName());

        Specification<User> specification = getSpecification(searchObj,sourceFlag);

        if (StringUtils.isEmpty(sortStr))
        {
            return userDao.findAll(specification,PageRequest.of(page, size));
        }
        else
        {
            return userDao.findAll(specification,PageRequest.of(page, size, new Sort((sortAscOrDesc ? Sort.Direction.ASC : Sort.Direction.DESC), sortStr)));
        }
    }
    private Specification getSpecification(String searchObj,Integer sourceFlag)
    {
//        (JSONObject) JSONValue.parse(searchObj);

        JSONObject search = JSONObject.parseObject(searchObj);

        Specification<User> specification = new Specification<User>()
        {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder)
            {


                List<Predicate> queryList = new ArrayList<Predicate>();

                if(sourceFlag!=0){
                    queryList.add(criteriaBuilder.equal(root.get("sourceFlag"), sourceFlag));
                }

                if (search.get("username") != null && !StringUtils.isEmpty(search.get("username") + ""))
                {
                    queryList.add(criteriaBuilder.like(root.get("username"), "%"+search.get("username") + "%"));
                }

                if (search.get("sourceFlag") != null && !StringUtils.isEmpty(search.get("sourceFlag") + ""))
                {
                    queryList.add(criteriaBuilder.equal(root.get("sourceFlag"), search.get("sourceFlag")));
                }
                if (queryList.size() > 0)
                {
                    criteriaQuery.where(criteriaBuilder.and(queryList.toArray(new Predicate[queryList.size()])));
                }

                return criteriaQuery.getRestriction();
            }
        };

        return specification;
    }
}
